package com.river.river_common.utils;


import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * String 工具类
 * Created by shuzheng on 2016/12/07.
 * Updated by Sandy on 2017/9/24
 */
public class StringUtil {

    private static Pattern linePattern = Pattern.compile("_(\\w)");
    private static Pattern humpPattern = Pattern.compile("[A-Z]");
    private static Pattern hostPattern = Pattern.compile("https{0,1}://[^/]*", Pattern.CASE_INSENSITIVE);
    /**
     * 资源路径
     */
    public static final String OSS_FILE_URL = "http://218.17.158.244:33404/fileresource/";

    private static final Logger logger = LoggerFactory.getLogger(StringUtil.class);


    /**
     * 下划线转驼峰
     *
     * @param str
     * @return
     */
    public static String lineToHump(String str) {
        if (null == str || "".equals(str)) {
            return str;
        }
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);

        str = sb.toString();
        str = str.substring(0, 1).toUpperCase() + str.substring(1);

        return str;
    }

    /**
     * 驼峰转下划线(简单写法，效率低于{@link #humpToLine2(String)})
     *
     * @param str
     * @return
     */
    public static String humpToLine(String str) {
        return str.replaceAll("[A-Z]", "_$0").toLowerCase();
    }

    /**
     * 驼峰转下划线,效率比上面高
     *
     * @param str
     * @return
     */
    public static String humpToLine2(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 首字母转小写
     *
     * @param s
     * @return
     */
    public static String toLowerCaseFirstOne(String s) {
        if (StringUtils.isBlank(s)) {
            return s;
        }
        if (Character.isLowerCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }

    /**
     * 首字母转大写
     *
     * @param s
     * @return
     */
    public static String toUpperCaseFirstOne(String s) {
        if (StringUtils.isBlank(s)) {
            return s;
        }
        if (Character.isUpperCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuffer()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }

    /**
     * object转String
     *
     * @param object
     * @return
     */
    public static String getString(Object object) {
        return getString(object, "");
    }

    public static String getString(Object object, String defaultValue) {
        if (null == object) {
            return defaultValue;
        }
        try {
            return object.toString();
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * object转Integer
     *
     * @param object
     * @return
     */
    public static int getInt(Object object) {
        return getInt(object, -1);
    }

    public static int getInt(Object object, Integer defaultValue) {
        if (null == object) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(object.toString());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * object转Boolean
     *
     * @param object
     * @return
     */
    public static boolean getBoolean(Object object) {
        return getBoolean(object, false);
    }

    public static boolean getBoolean(Object object, Boolean defaultValue) {
        if (null == object) {
            return defaultValue;
        }
        try {
            return Boolean.parseBoolean(object.toString());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 拆分code
     *
     * @param ids
     * @return
     */
    public static List<String> getIdList(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return null;
        }
        List<String> idsl = Lists.newArrayList();
        if (ids != null) {
            for (String idstr : ids.split("[,;\\s\\n]+")) {
                try {
                    if (StringUtils.isNotBlank(ids)) {
                        idsl.add(idstr);
                    }
                } catch (Exception e) {
                    //Log.info("【id类型转换【错误】】," + idstr);
                    continue;
                }
            }
        }
        return idsl.size() > 0 ? idsl : null;
    }

    /**
     * 拆分id
     *
     * @param ids
     * @return
     */
    public static List<String> getIdLists(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return null;
        }
        List<String> idsl = Lists.newArrayList();
        if (ids != null) {
            for (String idstr : ids.split("[,;\\s\\n]+")) {
                try {
                    if (StringUtils.isNotBlank(ids)) {
                        idsl.add(idstr);
                    }
                } catch (Exception e) {
                    //Log.info("【id类型转换【错误】】," + idstr);
                    continue;
                }
            }
        }
        return idsl.size() > 0 ? idsl : null;
    }

    /**
     * 正则表达式 小于5舍去，大于5取5
     *
     * @param value
     * @return
     */
    public static String roundFloat(String value) {
        return value.replaceAll("\\.[0-4]\\d*", "").replaceAll("\\.[5-9]\\d*", ".5");
    }

    /**
     * 正则表达式查询 host
     *
     * @param url
     * @return
     */
    public static String getHostFromUrl(String url) {
        Matcher m = hostPattern.matcher(url);
        return m.find() ? m.group(0) : url;
    }

    /**
     * 添加hostName
     *
     * @param url
     * @param hostName
     * @return
     */
    public static String addHostName(String url, String hostName) {
        if (hostName != null && url.indexOf(hostName) < 0) {
            url = hostName + url;
        }
        try {
            if (url.matches(".+?\\?[^=]+?=.*")) {
                url = url.substring(0, url.indexOf("=") + 1) + URLEncoder.encode(url.substring(url.lastIndexOf("=") + 1), "utf-8");
            } else {
                url = url.substring(0, url.lastIndexOf("/") + 1) + URLEncoder.encode(url.substring(url.lastIndexOf("/") + 1), "utf-8");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 批量添加hostName
     *
     * @param urls
     * @param hostName
     * @return
     */
    public static List<String> batchAddHostName(List<String> urls, String hostName) {
        return urls.stream().map(url -> addHostName(url, hostName)).collect(Collectors.toList());
    }

    /**
     * 查看编码
     *
     * @param str
     * @return
     */
    public static String getEncoding(String str) {
        String encode = "GB2312";
        try {
            // 判断是不是GB2312
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s = encode;
                return s; // 是的话，返回“GB2312“，以下代码同理
            }
        } catch (Exception exception) {
        }
        encode = "ISO-8859-1";
        try {
            // 判断是不是ISO-8859-1
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s1 = encode;
                return s1;
            }
        } catch (Exception exception1) {
        }
        encode = "UTF-8";
        try {
            // 判断是不是UTF-8
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s2 = encode;
                return s2;
            }
        } catch (Exception exception2) {
        }
        encode = "GBK";
        try {
            // 判断是不是GBK
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s3 = encode;
                return s3;
            }
        } catch (Exception exception3) {
        }
        // 如果都不是，说明输入的内容不属于常见的编码格式。
        return "no charSet matched";
    }

    /**
     * 判断是否包含 数组中的字符串
     *
     * @param targetString
     * @param strArray
     * @return
     */
    public static boolean isIndexOfArray(String targetString, String[] strArray) {
        if (strArray == null || strArray.length == 0) {
            return false;
        }
        if (StringUtils.isEmpty(targetString)) {
            return false;
        }
        for (String tmpStr : strArray) {
            if (targetString.indexOf(tmpStr) >= 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 统计重复的字符串
     *
     * @param dataList
     * @param classifier
     * @return
     */
    public static <T> List<String> checkSameStringValue(List<T> dataList, Function<? super T, String> classifier) {
        if (CollectionUtils.isEmpty(dataList)) {
            return null;
        }
        Map<String, Long> sameStringNumMapf = dataList.stream().map(classifier).collect(Collectors.groupingBy(str -> str, Collectors.counting()));
        return sameStringNumMapf.entrySet().stream()
                .filter(stringLongEntry -> stringLongEntry.getValue() > 1)
                .map(entry -> entry.getKey()).collect(Collectors.toList());
    }

    /**
     * 按分隔符 拆分字符串
     *
     * @param str
     * @return
     */
    public static Stream<String> splitToStream(String str) {
        if (StringUtils.isNotEmpty(str)) {
            return getIdList(str).stream();
        } else {
            return Stream.generate(() -> str).limit(1);
        }
    }


    /**
     * 按正则表达式查询
     *
     * @param regionStr
     * @param reg        正则表达式
     * @param groupIndex 匹配组的index （默认为不分组情况为0）
     * @return
     */
    public static List<String> getListByPartern(String regionStr, String reg, Integer groupIndex) {
        if (StringUtils.isEmpty(regionStr) || StringUtils.isEmpty(reg)) {
            return null;
        }
        if (groupIndex == null) {
            groupIndex = 0;
        }
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(regionStr);
        List<String> result = new ArrayList<>();
        while (matcher.find()) {
            if (matcher.groupCount() >= groupIndex) {
                result.add(matcher.group(groupIndex));
            }
        }
        return result;
    }

    public static List<String> getListByPartern(String regionStr, String reg) {
        if (StringUtils.isEmpty(regionStr) || StringUtils.isEmpty(reg)) {
            return null;
        }
        List<String> result;
        if (reg.contains(")(")) {
            result = getListByPartern(regionStr, reg, 2);
        } else {
            result = getListByPartern(regionStr, reg, 0);
        }
        return result;
    }

    /**
     * 判断字符串是否符合正则表达式
     *
     * @param regList 正则表达式列表
     * @param str     字符串
     * @return
     */
    public static boolean match(List<String> regList, String str) {
        if (CollectionUtils.isEmpty(regList)) {
            return true;
        }
        StringBuilder sb = new StringBuilder();
        for (String reg : regList) {
            sb.append("|").append(reg);
        }
        String pattern = sb.toString().replaceFirst("\\|", "");

        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        return r.matcher(str).find();
    }

    /**
     * 字符串通过字符char比较,如果比较不出，就按长度比较
     *
     * @param oneStr
     * @param otherStr
     * @return
     */
    public static int compareByChar(String oneStr, String otherStr) {
        if (oneStr == null) {
            return otherStr == null ? 0 : -1;
        }
        if (otherStr == null) {
            return 1;
        }
        int oneLength = oneStr.length();
        int otherLength = otherStr.length();
        if (oneStr.isEmpty() || oneStr.isEmpty()) {
            return oneLength - otherLength;
        }
        char[] oneChar = oneStr.toCharArray();
        char[] otherChars = otherStr.toCharArray();
        int minLength = oneLength - otherLength < 0 ? oneLength : otherLength;
        int result = 0;
        for (int i = 0; i < minLength; i++) {
            result = oneChar[i] - otherChars[i];
            if (result != 0) {
                break;
            }
        }
        if (result == 0) {
            return oneLength - otherLength;
        }
        return result;
    }


    /**
     * sql语句中 in的数量大于1000的时候，使用(in(..) or in (...))改写
     *
     * @param values
     * @param fieldName
     * @return
     */
    public static <T> String getInSqlWhenThanMaxNum(List<T> values, String fieldName) {
        if (CollectionUtils.isEmpty(values) || StringUtils.isEmpty(fieldName)) {
            return null;
        }
        List<List<T>> valueLists = Lists.partition(values, 1000);
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("(");
        List<String> sqlTmp = null;
        int index = 0;
        for (List<T> valuelist : valueLists) {
            if (index > 0) {
                sqlBuffer.append(" OR ");
            } else {
                index++;
            }
            sqlBuffer.append(fieldName);
            sqlBuffer.append(" in ('");
            sqlTmp = valuelist.stream().map(value -> value.toString()).collect(Collectors.toList());
            sqlBuffer.append(String.join("','", sqlTmp));
            sqlBuffer.append("') ");
        }
        sqlBuffer.append(" )");
        return new String(sqlBuffer);
    }


    /**
     * 字符串通过正则表达式过滤
     *
     * @param originStr
     * @param reg
     * @return
     */
    public static String replaceAllToEmptyStr(String originStr, String reg) {
        if (StringUtils.isEmpty(reg) || StringUtils.isEmpty(originStr)) {
            return originStr;
        }
        return originStr.replaceAll(reg, "");
    }

    /**
     * 获取没有html标签的文本
     *
     * @param content
     * @return
     */
    public static String getContentWithOutTag(String content) {
        return replaceAllToEmptyStr(content, "<[^<>]+?>");
    }


    /**
     * 从oss url查询文件名
     *
     * @param mapplicationUrl
     * @return
     */
    public static String getResourceNamefromUrl(String mapplicationUrl) {

        String resourceUrl = null;
        if (StringUtils.isNotEmpty(mapplicationUrl)) {
            try {
                resourceUrl = URLDecoder.decode(mapplicationUrl, "utf-8");
                resourceUrl = resourceUrl.replace(OSS_FILE_URL, "");
                //去除文件名后缀
                resourceUrl = resourceUrl.replaceAll("[\\.\\?].*", "");
                resourceUrl = resourceUrl.replaceAll("_[0-9]*$", "");
            } catch (UnsupportedEncodingException e) {
                logger.error("url解码失败", e);
            } catch (Exception e) {
                logger.error("url查询文件名 失败", e);
            }
        }
        return resourceUrl;
    }

    /**
     * 从oss url查询文件名 包括后缀
     *
     * @param mapplicationUrl
     * @return
     */
    public static String getResourceNameAndSuffixfromUrl(String mapplicationUrl) {

        String resourceUrl = null;
        if (StringUtils.isNotEmpty(mapplicationUrl)) {
            try {
                resourceUrl = URLDecoder.decode(mapplicationUrl, "utf-8");
                resourceUrl = resourceUrl.replace(OSS_FILE_URL, "");
                //去除参数
                resourceUrl = resourceUrl.replaceAll("\\?.*", "");
                resourceUrl = resourceUrl.replaceAll("_[0-9]+(?=\\.)", "");
            } catch (UnsupportedEncodingException e) {
                logger.error("url解码失败", e);
            } catch (Exception e) {
                logger.error("url查询文件名 失败", e);
            }
        }
        return resourceUrl;
    }

    public static void main(String[] args) {
        String url = "http://218.17.158.244:33404/fileresource/card_bg_48231424.png?AWSAccessKeyId=1q2w3e4r&Expires=1629703106&Signature=jNuH63ok2GcgcqeVv64NQXaCl3k%3D";
        System.out.println(getResourceNameAndSuffixfromUrl(url));

    }

}


